package com.xydtech.busiflw.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xydtech.busiflw.domain.*;
import com.xydtech.busiflw.mapper.*;
import com.xydtech.busiflw.service.IBusinessFlowLogicService;
import com.xydtech.busiflw.service.IBusinessFlowService;
import com.xydtech.common.config.unipush.UniPushConfig;
import com.xydtech.common.constant.Constants;
import com.xydtech.common.constant.FlowConstants;
import com.xydtech.common.core.domain.AjaxResult;
import com.xydtech.common.core.domain.entity.SysDept;
import com.xydtech.common.core.domain.entity.SysUser;
import com.xydtech.common.core.text.Convert;
import com.xydtech.common.utils.AESEncryptionUtils;
import com.xydtech.common.utils.DateUtils;
import com.xydtech.common.utils.StringUtils;
import com.xydtech.common.utils.string.StringUtil;
import com.xydtech.system.mapper.SysDeptMapper;
import com.xydtech.system.mapper.SysUserMapper;
import com.xydtech.workflow.domain.WflFlowstep;
import com.xydtech.workflow.domain.WflStepskip;
import com.xydtech.workflow.mapper.WflFlowstepMapper;
import com.xydtech.workflow.mapper.WflStepskipMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 业务流程实例Service业务层处理
 *
 * @author JHON
 * @date 2021-06-09
 */
@Slf4j
@Service
public class BusinessFlowServiceImpl implements IBusinessFlowService {
    @Autowired
    private BusiflInstanceMapper busiflInstanceMapper;
    @Autowired
    private BusiflWaitTaskMapper busiflWaitTaskMapper;
    @Autowired
    private BusiflInstStepMapper busiflInstStepMapper;
    @Autowired
    private WflFlowstepMapper wflFlowstepMapper;
    @Autowired
    private WflStepskipMapper wflStepskipMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private BusiflDocRegMapper busiflDocRegMapper;
    @Autowired
    private BusiflEcardMerchantMapper busiflEcardMerchantMapper;
    @Autowired
    private BusiflEcardMerchantImportMapper busiflEcardMerchantImportMapper;
    @Autowired
    private BusiflEcardCustomerGroupMerchantMapper busiflEcardCustomerGroupMerchantMapper;
    @Autowired
    private IBusinessFlowLogicService businessFlowLogicService;
    @Value(value = "${busiplat.MQEnabled}")
    private Boolean mqEnabled;


    /**
     * 查询业务流程实例
     *
     * @param instanceId 业务流程实例ID
     * @return 业务流程实例
     */
    @Override
    public BusiflInstance selectBusiflInstanceById(String instanceId) {
        return busiflInstanceMapper.selectBusiflInstanceById(instanceId);
    }

    /**
     * 初始化业务流程数据
     *
     * @param wflFlowstep
     * @param instanceId
     * @param userId
     * @param deptId
     * @param keyInfo
     * @return BusiflWaitTask
     * @throws
     * @author JHON
     * @Date 2021/6/11 15:13
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusiflWaitTask initBusinessFlowData(WflFlowstep wflFlowstep, Long flowId, String instanceId, Long userId, Long deptId, String keyInfo) {
        /**初始化流程实例表*/
        BusiflInstance busiflInstance = new BusiflInstance();
        busiflInstance.setInstanceId(instanceId);
        busiflInstance.setFlowId(flowId);
        busiflInstance.setVersionId(wflFlowstep.getVersionId());
        busiflInstance.setCreateUser(userId);
        busiflInstance.setCreateTime(new Date());
        //状态默认1-新建
        busiflInstance.setInstState("1");
        busiflInstance.setKeyInfo(keyInfo.toString());
        busiflInstanceMapper.insertBusiflInstance(busiflInstance);
        /**生成任务批次号*/
        String taskBatchId = new StringBuilder().append(DateUtils.dateTimeNow()).append(String.format("%0" + 8 + "d", wflFlowstep.getStepId() + userId)).toString();
        /**初始化流转步骤表*/
        BusiflInstStep busiflInstStep = new BusiflInstStep();
        busiflInstStep.setInstanceId(instanceId);
        busiflInstStep.setStepId(wflFlowstep.getStepId());
        busiflInstStep.setCreateUser(userId);
        busiflInstStep.setCreateTime(new Date());
        busiflInstStep.setTaskBatchId(taskBatchId);
        //状态待处理
        busiflInstStep.setSts("0");
        busiflInstStepMapper.insertBusiflInstStep(busiflInstStep);
        /**初始化资料上传登记表*/
        BusiflDocReg busiflDocReg = new BusiflDocReg();
        busiflDocReg.setInstanceId(instanceId);
        busiflDocReg.setVersionId(wflFlowstep.getVersionId());
        busiflDocRegMapper.insertBusiflDocReg(busiflDocReg);
        /**初始化待办任务表*/
        BusiflWaitTask busiflWaitTask = new BusiflWaitTask();
        busiflWaitTask.setInstanceId(instanceId);
        busiflWaitTask.setStepId(wflFlowstep.getStepId());
        busiflWaitTask.setBelongTo(userId);
        busiflWaitTask.setBelongOrg(deptId);
        busiflWaitTask.setTaskPolicy(wflFlowstep.getTaskPolicy());
        busiflWaitTask.setPerformer(userId);
        busiflWaitTask.setCreateTime(new Date());
        busiflWaitTask.setAccepteTime(new Date());
        busiflWaitTask.setTaskBatchId(taskBatchId);
        //任务类型1-暂存任务（流程第一步未提交）
        busiflWaitTask.setTaskType("1");
        //状态 1-开启 0-关闭
        busiflWaitTask.setSts("1");
        busiflWaitTaskMapper.insertBusiflWaitTask(busiflWaitTask);
        return busiflWaitTask;
    }

    /**
     * 提交任务
     *
     * @param versionId
     * @param instanceId
     * @param stepId
     * @param taskId
     * @param keyInfo
     * @param approveType
     * @param approveMemo
     * @param currentUser
     * @param choiceApproveUserList 任务多选时使用选择的审批人
     * @return com.xydtech.common.core.domain.AjaxResult
     * @throws
     * @Title: submitTask
     * @author JHON
     * @Date 2021/11/29 10:38
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult submitTask(Long versionId, String instanceId, Long stepId, Long taskId, String keyInfo, String approveType, String approveMemo, SysUser currentUser, String choiceApproveUserList, String salt) throws Exception {
        /**查询当前流程节点信息*/
        WflFlowstep currentStep = new WflFlowstep();
        currentStep.setVersionId(versionId);
        currentStep.setStepId(stepId);
        List<WflFlowstep> currentStepLis = wflFlowstepMapper.selectWflFlowstepList(currentStep);
        if (currentStepLis.size() == 0) {
            return AjaxResult.error("当前流程步骤配置信息丢失，请检查流程配置！");
        } else {
            currentStep = currentStepLis.get(0);
        }
        /**查询当前处理的任务信息*/
        BusiflWaitTask currentWaitTask = busiflWaitTaskMapper.selectBusiflWaitTaskById(taskId);
        if (currentWaitTask == null) {
            return AjaxResult.error("当前任务被删除！");
        } else if (FlowConstants.WAIT_TASK_CLOSE_STS.equals(currentWaitTask.getSts())) {
            return AjaxResult.error("当前任务被其他人提交！");
        }
        /**分派策略为3-任务并发或 4-任务多选并发特殊处理*/
        if (currentStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_3) || currentStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_4)) {
            return parallelTaskSubmit(currentStep, currentWaitTask, instanceId, currentUser, approveType, approveMemo, keyInfo, choiceApproveUserList, salt);
        } else {
            /**运行流程节点逻辑单元*/
            AjaxResult ajaxResult = businessFlowLogicService.flowLogicRunning(versionId, instanceId, stepId, keyInfo, approveType, currentUser);
            if (!Constants.SUCCESS.equals(ajaxResult.get(Constants.CODE).toString())) {
                return AjaxResult.error(ajaxResult.get(Constants.MSG).toString());
            }
            if (approveType.startsWith(FlowConstants.APPROVE_TYPE_T)) {
                String nextStepName = "";
                /**同意时，如果当前步骤节点不是结束节点或者分派策略为3-任务并发或 4-任务多选并发且还有其他并发未处理则不生成待办任务*/
                if (!FlowConstants.STEP_TYPE_END.equals(currentStep.getStepType())) {
                    /**查询下一个流程节点信息*/
                    WflFlowstep nextStep = getNextStepInfo(versionId, currentStep.getOrderNum(), instanceId, keyInfo);
                    nextStepName = nextStep.getStepName();
                    /**生成任务批次号*/
                    String taskBatchId = new StringBuilder().append(DateUtils.dateMillisecondNow()).append(String.format("%0" + 8 + "d", nextStep.getStepId() + currentUser.getUserId())).toString();

                    /**查询下一节点审批人*/
                    List<SysUser> userList = getApproveUserList(instanceId, nextStep, currentUser, choiceApproveUserList, salt);
                    if (userList.size() > 0) {
                        if (nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_3) || nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_4)) {
                            /**下一节点分派策略是3-任务并发或 4-任务多选并发，判断下一节点审批人数量是否满足参与人数限制条件*/
                            if (userList.size() < nextStep.getApprovPop()) {
                                return AjaxResult.error("下一审批环节【" + nextStep.getStepName() + "】需要" + nextStep.getApprovPop() + "人审批，请给该岗位分配更多人员！");
                            }
                        }
                        /**生成下一节点待办任务*/
                        if (nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_1) || nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_2)) {
                            /**下一节点分派策略是1-任务抢先 2-任务多选抢先，初始化流程步骤信息时步骤处理人为空，只生成一条步骤信息*/
                            insertBusiflInstStep(instanceId, taskBatchId, nextStep, currentUser, null);
                            for (SysUser nextUser : userList) {
                                /**创建下一节点待办任务*/
                                createTask(versionId, instanceId, taskBatchId, nextStep, currentUser, nextUser, "2", FlowConstants.APPROVE_TYPE_T, keyInfo, nextStep.getStepName());
                            }
                        } else if (nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_3) || nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_4)) {
                            for (SysUser nextUser : userList) {
                                /**创建下一节点待办任务*/
                                createTask(versionId, instanceId, taskBatchId, nextStep, currentUser, nextUser, "2", FlowConstants.APPROVE_TYPE_T, keyInfo, nextStep.getStepName());
                                /**下一节点分派策略是3-任务并发或 4-任务多选并发，初始化流程步骤信息时步骤处理人为接收人，每个人都生成步骤信息*/
                                insertBusiflInstStep(instanceId, taskBatchId, nextStep, currentUser, nextUser);
                            }
                        }
                    } else {
                        return AjaxResult.error("下一审批环节【" + nextStep.getStepName() + "】未配置审批信息！");
                    }

                }
                /**关闭当前任务*/
                closeTask(instanceId, currentWaitTask, currentStep, currentUser, approveType, approveMemo);
                if ("".equals(nextStepName)) {
                    /**
                     * 2024年10月11日10:25:36 yjs
                     * 判断流程是否结束，流程审批结束后需要处理对应的业务数据，当前只有电子名片删除走流程，后续新增其他流程需要修改
                     * keyInfo内数据说明：
                     * busiId:业务编号
                     * cname:客户名称
                     * busiType:业务类型，busiType  1-商户信息，2-企业信息，3-企业楼宇（厂区），4-个人信息，5-个人网格，6.-农业主体信息
                     * 7-商户信息，8-企业信息，9-个人信息，10.-新型农业主体，11-行业客户删除，12-社团组织删除
                     */
                    JSONObject jsonObject = JSONObject.parseObject(keyInfo);
                    /**
                     * 1、判断业务类型
                     * 2、根据业务ID删除/停用
                     */
                    Long busiId = jsonObject.getLong("busiId");//商户信息的主键id

                    switch (jsonObject.getString("busiType")) {
                        case "1":
                            //商户信息删除/停用
                            //查询是否存在未处理营销任务
                            BusiflEcardMerchantTask merchantTask = busiflEcardMerchantMapper.getMerchantTaskByMerchantId(busiId, "2");//商户类型：1-个人，2-商户，3-企业，4-新型农业主体
                            if (merchantTask != null) {
                                //存在则更新为已完成
                                merchantTask.setTaskSts("1");
                                busiflEcardMerchantMapper.updateEcardMerchantTask(merchantTask);
                            }
                            //同步修改行业客户状态
                            BusiEcardCustomerGroupMerchant merGroupMerchant = busiflEcardCustomerGroupMerchantMapper.selectEcardCustomerGroupMerchantByMerchantId(busiId, "2");
                            if (merGroupMerchant != null) {
                                busiflEcardMerchantMapper.changeIndustrialCustomerStatus(merGroupMerchant.getId());
                            }
                            busiflEcardMerchantMapper.changeMerchantStatus(busiId);
                            break;
                        case "2":
                            //企业信息删除/停用
                            //查询是否存在未处理营销任务
                            BusiflEcardMerchantTask enterpriseTask = busiflEcardMerchantMapper.getMerchantTaskByMerchantId(busiId, "3");//商户类型：1-个人，2-商户，3-企业，4-新型农业主体
                            if (enterpriseTask != null) {
                                //存在则更新为已完成
                                enterpriseTask.setTaskSts("1");
                                busiflEcardMerchantMapper.updateEcardMerchantTask(enterpriseTask);
                            }
                            //同步修改行业客户状态
                            BusiEcardCustomerGroupMerchant entGroupMerchant = busiflEcardCustomerGroupMerchantMapper.selectEcardCustomerGroupMerchantByMerchantId(busiId, "3");
                            if (entGroupMerchant != null) {
                                busiflEcardMerchantMapper.changeIndustrialCustomerStatus(entGroupMerchant.getId());
                            }
                            busiflEcardMerchantMapper.changeEnterpriseStatus(busiId);
                            break;
                        case "3":
                            //企业楼宇（厂区）删除/停用
                            busiflEcardMerchantMapper.changeLocationStatus(busiId);
                            break;
                        case "4":
                            //查询是否存在未处理营销任务
                            BusiflEcardMerchantTask personTask = busiflEcardMerchantMapper.getMerchantTaskByMerchantId(busiId, "1");//商户类型：1-个人，2-商户，3-企业，4-新型农业主体
                            if (personTask != null) {
                                //存在则更新为已完成
                                personTask.setTaskSts("1");
                                busiflEcardMerchantMapper.updateEcardMerchantTask(personTask);
                            }
                            //同步修改行业客户状态
                            BusiEcardCustomerGroupMerchant perGroupMerchant = busiflEcardCustomerGroupMerchantMapper.selectEcardCustomerGroupMerchantByMerchantId(busiId, "1");
                            if (perGroupMerchant != null) {
                                busiflEcardMerchantMapper.changeIndustrialCustomerStatus(perGroupMerchant.getId());
                            }
                            //个人信息删除/停用
                            busiflEcardMerchantMapper.changePersonStatus(busiId);
                            break;
                        case "5":
                            //个人网格删除/停用
                            busiflEcardMerchantMapper.changePersonAreaStatus(busiId);
                            break;
                        case "6":
                            //农业主体信息删除/停用
                            //查询是否存在未处理营销任务
                            BusiflEcardMerchantTask agricultureTask = busiflEcardMerchantMapper.getMerchantTaskByMerchantId(busiId, "4");//商户类型：1-个人，2-商户，3-企业，4-新型农业主体
                            if (agricultureTask != null) {
                                //存在则更新为已完成
                                agricultureTask.setTaskSts("1");
                                busiflEcardMerchantMapper.updateEcardMerchantTask(agricultureTask);
                            }
                            //同步修改行业客户状态
                            BusiEcardCustomerGroupMerchant agrGroupMerchant = busiflEcardCustomerGroupMerchantMapper.selectEcardCustomerGroupMerchantByMerchantId(busiId, "4");
                            if (agrGroupMerchant != null) {
                                busiflEcardMerchantMapper.changeIndustrialCustomerStatus(agrGroupMerchant.getId());
                            }
                            busiflEcardMerchantMapper.changeAgricultureStatus(busiId);
                            break;
                        case "7":
                            //个体工商户停用/任务停用

                            BusiflEcardMerchantImportTask busiflEcardMerchantImportTask = busiflEcardMerchantImportMapper.selectEcardMerchantImportTaskByTaskId(busiId);
                            busiflEcardMerchantImportMapper.closeMerchantImport(busiflEcardMerchantImportTask.getImportId());

                            busiflEcardMerchantImportTask.setSts("1");
                            busiflEcardMerchantImportTask.setCloseTime(new Date());
                            busiflEcardMerchantImportMapper.updateEcardMerchantImportTask(busiflEcardMerchantImportTask);
                            break;
                        case "8":
                            //企业停用/任务停用
                            break;
                        case "9":
                            //个人停用/任务停用
                            break;
                        case "10":
                            //新型农业主体停用/任务停用
                            break;
                        case "11":
                            //行业客户删除/停用
                            BusiEcardCustomerGroupMerchant groupMerchant = busiflEcardCustomerGroupMerchantMapper.selectEcardCustomerGroupMerchantById(busiId);
                            Long merchantId = groupMerchant.getMerchantId();//商户id
                            String merchantType = groupMerchant.getMerchantType();//商户类型：1-个人，2-商户，3-企业，4-新型农业主体
                            //查询是否存在未处理营销任务
                            BusiflEcardMerchantTask ecardMerchantTask = busiflEcardMerchantMapper.getMerchantTaskByMerchantId(busiId, merchantType);//商户类型：1-个人，2-商户，3-企业，4-新型农业主体
                            if (ecardMerchantTask != null) {
                                //存在则更新为已完成
                                ecardMerchantTask.setTaskSts("1");
                                busiflEcardMerchantMapper.updateEcardMerchantTask(ecardMerchantTask);
                            }
                            //根据商户id和商户类型去修改对应商户信息表中的状态
                            if ("1".equals(merchantType)) {//个人
                                busiflEcardMerchantMapper.changePersonStatus(merchantId);
                            }
                            if ("2".equals(merchantType)) {//商户
                                busiflEcardMerchantMapper.changeMerchantStatus(merchantId);
                            }
                            if ("3".equals(merchantType)) {//企业
                                busiflEcardMerchantMapper.changeEnterpriseStatus(merchantId);
                            }
                            if ("4".equals(merchantType)) {//新型农业主体
                                busiflEcardMerchantMapper.changeAgricultureStatus(merchantId);
                            }
                            //修改行业客户状态
                            busiflEcardMerchantMapper.changeIndustrialCustomerStatus(busiId);
                            break;
                        case "12":
                            //社团组织删除/停用
                            busiflEcardMerchantMapper.changeOrganizeStatus(busiId);
                            break;
                        default:
                            break;
                    }
                    return AjaxResult.success("同意提交成功！");
                } else {
                    return AjaxResult.success("提交到" + nextStepName + "环节！");
                }
            } else if (approveType.startsWith(FlowConstants.APPROVE_TYPE_F)) {
                /**拒件*/
                /**关闭当前任务*/
                closeTask(instanceId, currentWaitTask, currentStep, currentUser, approveType, approveMemo);
                return AjaxResult.success("拒件成功");
            } else if (approveType.startsWith(FlowConstants.APPROVE_TYPE_R)) {
                //退回
                /**查询退回到的业务流程步骤处理信息*/
                BusiflInstStep returnInstStep = new BusiflInstStep();
                returnInstStep.setStepId(Long.valueOf(approveType.replace("R", "")));
                returnInstStep.setInstanceId(instanceId);
                returnInstStep.setSts("1");
                List<BusiflInstStep> returnInstStepList = busiflInstStepMapper.selectcorrelationUserList(returnInstStep);
                //查询退回节点信息
                WflFlowstep returnNextStep = new WflFlowstep();
                returnNextStep.setStepId(returnInstStep.getStepId());
                returnNextStep.setVersionId(versionId);
                List<WflFlowstep> returnNextStepList = wflFlowstepMapper.selectWflFlowstepList(returnNextStep);
                /**生成任务批次号*/
                String taskBatchId = new StringBuilder().append(DateUtils.dateMillisecondNow()).append(String.format("%0" + 8 + "d", returnNextStep.getStepId() + currentUser.getUserId())).toString();
                /**下一节点 是任务抢先，生成一条数据，任务并发生成多条数据*/
                if (FlowConstants.TASK_POLICY_1.equals(returnNextStepList.get(0).getTaskPolicy()) || FlowConstants.TASK_POLICY_2.equals(returnNextStepList.get(0).getTaskPolicy())) {
                    //获取退回节点当时的处理人
                    SysUser nextUser = sysUserMapper.selectUserById(returnInstStepList.get(0).getStopUser());
                    if (nextUser != null) {
                        try {
                            //数据解密（手机号、身份证号）
                            if (!StringUtils.objIsNullOrEmpty(nextUser.getPhonenumber())) {
                                nextUser.setPhonenumber(AESEncryptionUtils.decrypt(nextUser.getPhonenumber(), salt));
                            }
                            if (!StringUtils.objIsNullOrEmpty(nextUser.getCardNum())) {
                                nextUser.setCardNum(AESEncryptionUtils.decrypt(nextUser.getCardNum(), salt));
                            }
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }
                    if (nextUser == null) {
                        return AjaxResult.error("退回节点接收人不存在，可能该用户已被删除或停用！");
                    }
                    /**生成业务流程节点数据*/
                    insertBusiflInstStep(instanceId, taskBatchId, returnNextStepList.get(0), currentUser, nextUser);
                    /**创建下一节点待办任务*/
                    createTask(versionId, instanceId, taskBatchId, returnNextStepList.get(0), currentUser, nextUser, "3", FlowConstants.APPROVE_TYPE_R, keyInfo, returnNextStepList.get(0).getStepName());
                } else {
                    for (int i = 0; i < returnInstStepList.size(); i++) {
                        //获取退回节点当时的处理人
                        SysUser nextUser = sysUserMapper.selectUserById(returnInstStepList.get(i).getStopUser());
                        if (nextUser != null) {
                            try {
                                //数据解密（手机号、身份证号）
                                if (!StringUtils.objIsNullOrEmpty(nextUser.getPhonenumber())) {
                                    nextUser.setPhonenumber(AESEncryptionUtils.decrypt(nextUser.getPhonenumber(), salt));
                                }
                                if (!StringUtils.objIsNullOrEmpty(nextUser.getCardNum())) {
                                    nextUser.setCardNum(AESEncryptionUtils.decrypt(nextUser.getCardNum(), salt));
                                }
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        }
                        if (nextUser == null) {
                            return AjaxResult.error("退回节点接收人不存在，可能该用户被删除或停用！");
                        }
                        /**创建退回节点待办任务*/
                        createTask(versionId, instanceId, taskBatchId, returnNextStepList.get(0), currentUser, nextUser, "3", FlowConstants.APPROVE_TYPE_R, keyInfo, returnNextStepList.get(0).getStepName());
                        /**退回节点节点分派策略是2-任务并发或 3-任务多选并发，步骤处理人为接收人，每个人都生成步骤信息*/
                        insertBusiflInstStep(instanceId, taskBatchId, returnNextStepList.get(0), currentUser, nextUser);
                    }
                }

                /**关闭当前任务*/
                closeTask(instanceId, currentWaitTask, currentStep, currentUser, approveType, approveMemo);
                return AjaxResult.success("退回到" + returnNextStepList.get(0).getStepName() + "环节！");
            } else {
                return AjaxResult.error("未获取到审批意见信息，请检查流程配置，确保对应岗位分配人员！");
            }
        }

    }

    /**
     * 流程提交获取下一步骤节点信息
     *
     * @param versionId
     * @param orderNum
     * @param keyInfo
     * @return com.xydtech.workflow.domain.WflFlowstep
     * @throws
     * @Title: getNextStepInfo
     * @author JHON
     * @Date 2021/12/3 15:35
     **/
    @Override
    public WflFlowstep getNextStepInfo(Long versionId, Long orderNum, String instanceId, String keyInfo) {
        WflFlowstep nextStepInfo = new WflFlowstep();
        //查询剩余流程节点信息
        List<WflFlowstep> nextStepList = wflFlowstepMapper.selectFollowUpStepByVersionIdAndOrderNum(versionId, orderNum);
        if (nextStepList.size() > 0) {
            for (WflFlowstep nextStep : nextStepList) {
                /**结束节点不判断跳过条件*/
                if (FlowConstants.STEP_TYPE_END.equals(nextStep.getStepType())) {
                    nextStepInfo = nextStep;
                    break;
                }
                /**判断是否满足节点跳过条件*/
                boolean skipResult = this.getSkipResult(nextStep, instanceId, keyInfo);
                if (!skipResult) {
                    nextStepInfo = nextStep;
                    break;
                }
            }
        }
        return nextStepInfo;
    }

    /**
     * 判断流程节点跳过条件是否满足
     *
     * @param wflFlowstep
     * @param keyInfo
     * @return boolean
     * @throws
     * @Title: getSkipResult
     * @author JHON
     * @Date 2021/12/3 15:38
     **/
    public boolean getSkipResult(WflFlowstep wflFlowstep, String instanceId, String keyInfo) {
        WflStepskip wflStepskip = new WflStepskip();
        wflStepskip.setVersionId(wflFlowstep.getVersionId());
        wflStepskip.setStepId(wflFlowstep.getStepId());
        //遍历节点的跳过条件，满足条件则继续判断下一节点
        List<WflStepskip> skipList = wflStepskipMapper.selectWflStepskipList(wflStepskip);
        if (skipList.size() == 0) {
            //未配置跳过条件
            return false;
        } else {
            //跳过条件组合方式1-与 2-或
            String groupType = wflFlowstep.getGroupType();
            // 组装SQL
            StringBuffer isSkipSql = new StringBuffer();
            isSkipSql.append("select (case   when ");
            for (int i = 0; i < skipList.size(); i++) {
                //第一次的时候不需要加and/or
                if (i == 0) {
                    isSkipSql.append("( ");
                } else {
                    if ("1".equals(groupType)) {
                        isSkipSql.append(" and ( ");
                    } else {
                        isSkipSql.append(" or ( ");
                    }
                }
                //拼装跳过条件取值SQL
                isSkipSql.append(skipList.get(i).getValSql());
                isSkipSql.append(") ");
                //拼装跳过条件比较方式：>,<,>=,<=,<>等等，字符串只有=和<>
                isSkipSql.append(skipList.get(i).getCompareType());
                //拼装跳过条件比较值
                isSkipSql.append(skipList.get(i).getCompareVal());
            }
            isSkipSql.append(" then 'true' else'false' end) is_can_skip from dual");
            Map<String, Object> params = new HashMap<>();
            /**取值执行的SQL*/
            params.put("valSql", isSkipSql.toString());
            /**执行的SQL的参数*/
            HashMap paramsMap = JSON.parseObject(keyInfo, HashMap.class);
            params.putAll(paramsMap);
            params.put("applyId", instanceId);
            return busiflInstStepMapper.selectStepSkipResult(params);
        }
    }

    /**
     * 根据流程节点配置信息获取节点审批人
     *
     * @param instanceId            业务实例
     * @param nextStep              下一流程节点
     * @param currentUser           当前用户
     * @param choiceApproveUserList 任务多选时使用选择的审批人
     * @return java.util.List<com.xydtech.common.core.domain.entity.SysUser>
     * @throws
     * @Title: getApproveUserList
     * @author JHON
     * @Date 2021/11/29 13:58
     **/
    @Override
    public List<SysUser> getApproveUserList(String instanceId, WflFlowstep nextStep, SysUser currentUser, String choiceApproveUserList, String salt) {
        List<SysUser> userList = new ArrayList<>();
        //任务模式判断
        if (FlowConstants.TASK_MODE_USER.equals(nextStep.getTaskMode())) {
            /**任务定位-指定用户*/
            if (FlowConstants.TASK_POSITION_1.equals(nextStep.getTaskPosition())) {
                //1 - 当前用户本人
                userList.add(currentUser);
            } else if (FlowConstants.TASK_POSITION_2.equals(nextStep.getTaskPosition())) {
                //2 - 关联步提交人
                /**任务索引（任务定位为 2-关联步提交人，存关联步骤编号；
                 为4-当前机构指定岗位5-上级机构指定岗位6-指定机构指定岗位7-任意机构指定岗位，存岗位编号）*/
                Long taskIndex = nextStep.getTaskIndex();
                BusiflInstStep busiflInstStep = new BusiflInstStep();
                busiflInstStep.setStepId(taskIndex);
                busiflInstStep.setInstanceId(instanceId);
                busiflInstStep.setSts("1");
                List<BusiflInstStep> instStepList = busiflInstStepMapper.selectcorrelationUserList(busiflInstStep);
                if (instStepList.size() > 0) {
                    for (BusiflInstStep instStep : instStepList) {
                        SysUser correlationUser = sysUserMapper.selectUserById(instStep.getStopUser());
                        if (correlationUser != null) {
                            try {
                                //数据解密（手机号、身份证号）
                                if (!StringUtils.objIsNullOrEmpty(correlationUser.getPhonenumber())) {
                                    correlationUser.setPhonenumber(AESEncryptionUtils.decrypt(correlationUser.getPhonenumber(), salt));
                                }
                                if (!StringUtils.objIsNullOrEmpty(correlationUser.getCardNum())) {
                                    correlationUser.setCardNum(AESEncryptionUtils.decrypt(correlationUser.getCardNum(), salt));
                                }
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        }
                        userList.add(correlationUser);
                    }
                }
            } else if (FlowConstants.TASK_POSITION_3.equals(nextStep.getTaskPosition())) {
                //3 - 自定义SQL
                Map<String, Object> params = new HashMap<>();
                /**取值执行的SQL*/
                params.put("valSql", nextStep.getDefineSql());
                /**执行的SQL的参数*/
                params.put("instanceId", instanceId);
                List<Long> list = busiflInstStepMapper.selectDefineSqlUserList(params);
                if (list.size() > 0) {
                    for (Long userId : list) {
                        SysUser defineUser = sysUserMapper.selectUserById(userId);
                        if (defineUser != null) {
                            try {
                                //数据解密（手机号、身份证号）
                                if (!StringUtils.objIsNullOrEmpty(defineUser.getPhonenumber())) {
                                    defineUser.setPhonenumber(AESEncryptionUtils.decrypt(defineUser.getPhonenumber(), salt));
                                }
                                if (!StringUtils.objIsNullOrEmpty(defineUser.getCardNum())) {
                                    defineUser.setCardNum(AESEncryptionUtils.decrypt(defineUser.getCardNum(), salt));
                                }
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        }
                        userList.add(defineUser);
                    }
                }
            }
        } else if (FlowConstants.TASK_MODE_POST.equals(nextStep.getTaskMode())) {
            /**任务定位-指定岗位 */
            if (StringUtil.isNullOrEmpty(choiceApproveUserList)) {
                //审批机构
                Long approveDeptId = 1L;
                if (FlowConstants.TASK_POSITION_4.equals(nextStep.getTaskPosition())) {
                    //4-当前机构指定岗位
                    approveDeptId = currentUser.getDeptId();
                } else if (FlowConstants.TASK_POSITION_5.equals(nextStep.getTaskPosition())) {
                    //5-上级机构指定岗位
                    approveDeptId = currentUser.getDept().getParentId();
                } else if (FlowConstants.TASK_POSITION_6.equals(nextStep.getTaskPosition())) {
                    //6-指定机构指定岗位
                    approveDeptId = nextStep.getTaskOrgId();
                } else if (FlowConstants.TASK_POSITION_7.equals(nextStep.getTaskPosition())) {
                    //7-任意机构指定岗位,当前法人下任意机构指定岗位
                    SysDept dept = sysDeptMapper.selectSecondLevelDeptByDeptId(currentUser.getDeptId());
                    if (dept != null) {
                        approveDeptId = dept.getDeptId();
                    }
                }
                /**过滤上步提交人*/
                if (FlowConstants.LAST_STEP_FILTER.equals(nextStep.getLaststepFilter())) {
                    //根据岗位部门查询用户列表，排除当前用户
                    if (FlowConstants.TASK_POSITION_7.equals(nextStep.getTaskPosition())) {
                        userList = sysUserMapper.selectAllUserListByPostAndDeptIdExcludeUser(approveDeptId, nextStep.getTaskIndex(), currentUser.getUserId());
                    } else {
                        userList = sysUserMapper.selectUserListByPostAndDeptIdExcludeUser(approveDeptId, nextStep.getTaskIndex(), currentUser.getUserId());
                    }

                } else {
                    //根据岗位部门查询用户列表
                    if (FlowConstants.TASK_POSITION_7.equals(nextStep.getTaskPosition())) {
                        userList = sysUserMapper.selectAllUserListByPostAndDeptId(approveDeptId, nextStep.getTaskIndex());
                    } else {
                        userList = sysUserMapper.selectUserListByPostAndDeptId(approveDeptId, nextStep.getTaskIndex());
                    }
                }
            } else {
                userList = sysUserMapper.selectUserByIds(Convert.toLongArray(choiceApproveUserList));
                if (userList.size() > 0) {
                    for (SysUser sysUser : userList) {
                        try {
                            //数据解密（手机号、身份证号）
                            if (!StringUtils.objIsNullOrEmpty(sysUser.getPhonenumber())) {
                                sysUser.setPhonenumber(AESEncryptionUtils.decrypt(sysUser.getPhonenumber(), salt));
                            }
                            if (!StringUtils.objIsNullOrEmpty(sysUser.getCardNum())) {
                                sysUser.setCardNum(AESEncryptionUtils.decrypt(sysUser.getCardNum(), salt));
                            }
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        }
        return userList;
    }

    /**
     * 生成业务流程步骤信息
     *
     * @param instanceId  流程实例号
     * @param taskBatchId 任务批次号
     * @param nextStep    下一节点流程信息
     * @param currentUser 当前提交用户
     * @param nextUser    下一节点审批人
     * @return void
     * @throws
     * @Title: insertBusiflInstStep
     * @author JHON
     * @Date 2021/11/29 15:15
     **/
    public void insertBusiflInstStep(String instanceId, String taskBatchId, WflFlowstep nextStep, SysUser currentUser, SysUser nextUser) {
        /**初始化流转步骤表*/
        BusiflInstStep nextInstStep = new BusiflInstStep();
        nextInstStep.setInstanceId(instanceId);
        nextInstStep.setTaskBatchId(taskBatchId);
        nextInstStep.setStepId(nextStep.getStepId());
        nextInstStep.setCreateUser(currentUser.getUserId());
        if (nextUser != null) {
            nextInstStep.setStopUser(nextUser.getUserId());
        }
        nextInstStep.setCreateTime(new Date());
        //状态待处理
        nextInstStep.setSts("0");
        busiflInstStepMapper.insertBusiflInstStep(nextInstStep);
    }

    /**
     * 创建待办任务
     *
     * @param versionId   流程版本ID
     * @param instanceId
     * @param taskBatchId 任务批次号
     * @param nextStep
     * @param currentUser
     * @param nextUser
     * @param taskType
     * @return void
     * @throws
     * @Title: createTask
     * @author JHON
     * @Date 2021/11/29 16:43
     **/
    public void createTask(Long versionId, String instanceId, String taskBatchId, WflFlowstep nextStep,
                           SysUser currentUser, SysUser nextUser, String taskType, String approveType, String keyInfo,
                           String flowName) {

        BusiflWaitTask busiflWaitTask = new BusiflWaitTask();
        busiflWaitTask.setInstanceId(instanceId);
        busiflWaitTask.setTaskBatchId(taskBatchId);
        busiflWaitTask.setStepId(nextStep.getStepId());
        busiflWaitTask.setBelongTo(nextUser.getUserId());
        busiflWaitTask.setBelongOrg(nextUser.getDeptId());
        busiflWaitTask.setTaskPolicy(nextStep.getTaskPolicy());
        busiflWaitTask.setPerformer(currentUser.getUserId());
        busiflWaitTask.setCreateTime(new Date());
        busiflWaitTask.setAccepteTime(new Date());
        //任务类型  1-暂存任务（流程第一步未提交） 2-提交任务 3-退回任务
        busiflWaitTask.setTaskType(taskType);
        //状态 1-开启 0-关闭
        busiflWaitTask.setSts("1");
        busiflWaitTaskMapper.insertBusiflWaitTask(busiflWaitTask);
        /**修改流程实例表*/
        BusiflInstance busiflInstance = new BusiflInstance();
        busiflInstance.setInstanceId(instanceId);
        //状态2-流转
        busiflInstance.setInstState("2");
        busiflInstanceMapper.updateBusiflInstance(busiflInstance);

        //判断系统是否开启了MQ消息推送
        if (mqEnabled) {
            //组装并发送UNIPUSH消息推送到消息队列中，等待消费者进行处理
            packageAndSendAppUniPushMessage(nextUser.getUserId(), busiflWaitTask.getTaskId(), versionId, instanceId, nextStep.getStepId(), approveType, keyInfo, flowName);
        }

    }


    /**
     * 关闭任务（任务类型为抢先任务）
     *
     * @param instanceId      实例号
     * @param currentWaitTask 当前任务
     * @param currentStep     当前流程节点
     * @param currentUser     当前提交人
     * @param approveType     审批意见
     * @return void
     * @throws
     * @Title: closeTask
     * @author JHON
     * @Date 2021/11/29 15:49
     **/
    @Transactional(rollbackFor = Exception.class)
    public void closeTask(String instanceId, BusiflWaitTask currentWaitTask, WflFlowstep currentStep, SysUser currentUser, String approveType, String approveMemo) {
        //1.关闭待办
        BusiflWaitTask busiflWaitTask = new BusiflWaitTask();
        busiflWaitTask.setSts("0");
        busiflWaitTask.setStopTime(DateUtils.getNowDate());
        busiflWaitTask.setTaskId(currentWaitTask.getTaskId());
        busiflWaitTask.setStepId(currentStep.getStepId());
        busiflWaitTask.setInstanceId(instanceId);
        busiflWaitTask.setTaskBatchId(currentWaitTask.getTaskBatchId());
        //2.更新流程步骤审批信息及处理状态为已处理
        BusiflInstStep busiflInstStep = new BusiflInstStep();
        busiflInstStep.setStopUser(currentUser.getUserId());
        busiflInstStep.setStopTime(DateUtils.getNowDate());
        busiflInstStep.setApproveType(approveType);
        busiflInstStep.setApproveMemo(approveMemo);
        busiflInstStep.setSts("1");
        busiflInstStep.setInstanceId(instanceId);
        busiflInstStep.setTaskBatchId(currentWaitTask.getTaskBatchId());
        busiflInstStep.setStepId(currentStep.getStepId());
        busiflWaitTaskMapper.updateBusiflWaitTask(busiflWaitTask);
        busiflInstStepMapper.updateBusiflInstStep(busiflInstStep);
        if (FlowConstants.APPROVE_TYPE_F.equals(approveType) || (FlowConstants.STEP_TYPE_END.equals(currentStep.getStepType()) && FlowConstants.APPROVE_TYPE_T.equals(approveType))) {
            //如果是拒件或者结束节点则关闭流程实例，迁移待办数据到历史任务
            closeInstance(instanceId, currentWaitTask, currentUser);
        }
    }

    /**
     * 关闭并发任务
     *
     * @param instanceId
     * @param currentWaitTask
     * @param currentStep
     * @param currentUser
     * @param approveType
     * @param approveMemo
     * @param untreatedTask
     * @return void
     * @throws
     * @Title: closeParallelTask
     * @author JHON
     * @Date 2022/10/26 10:28
     **/
    @Transactional(rollbackFor = Exception.class)
    public void closeParallelTask(String instanceId, BusiflWaitTask currentWaitTask, WflFlowstep currentStep, SysUser currentUser, String approveType, String approveMemo, int untreatedTask) {
        //1.关闭待办
        BusiflWaitTask busiflWaitTask = new BusiflWaitTask();
        busiflWaitTask.setSts("0");
        busiflWaitTask.setStopTime(DateUtils.getNowDate());
        busiflWaitTask.setTaskId(currentWaitTask.getTaskId());
        busiflWaitTask.setStepId(currentStep.getStepId());
        busiflWaitTask.setInstanceId(instanceId);
        busiflWaitTask.setTaskBatchId(currentWaitTask.getTaskBatchId());
        //2.更新流程步骤审批信息及处理状态为已处理
        BusiflInstStep busiflInstStep = new BusiflInstStep();
        busiflInstStep.setStopUser(currentUser.getUserId());
        busiflInstStep.setStopTime(DateUtils.getNowDate());
        busiflInstStep.setApproveType(approveType);
        busiflInstStep.setApproveMemo(approveMemo);
        busiflInstStep.setSts("1");
        busiflInstStep.setInstanceId(instanceId);
        busiflInstStep.setTaskBatchId(currentWaitTask.getTaskBatchId());
        busiflInstStep.setStepId(currentStep.getStepId());
        //当前步骤节点是并发策略的话需要判断并发审批模式（1-正常模式 2-投票模式）
        if (FlowConstants.APPROVE_MODE_1.equals(currentStep.getApprovMode())) {
            /**审批意见为同意*/
            if (FlowConstants.APPROVE_TYPE_T.equals(approveType)) {
                /** 如果当前任务是并发、并发审批模式1-正常模式、审批意见为同意，则只关闭当前节点归属自己的任务和步骤信息*/
                busiflWaitTaskMapper.updateBusiflWaitTask(busiflWaitTask);
                busiflInstStepMapper.updateBusiflInstStepByUser(busiflInstStep);
                if (untreatedTask == 1 && FlowConstants.STEP_TYPE_END.equals(currentStep.getStepType())) {
                    //如果是结束节点,并且剩余最后一个任务，则关闭流程实例，迁移待办数据到历史任务
                    closeInstance(instanceId, currentWaitTask, currentUser);
                }
            } else if (approveType.startsWith(FlowConstants.APPROVE_TYPE_R)) {
                /** 审批意见为退回，退回到指定节点，关闭当前节点归属所有任务和步骤信息*/
                busiflWaitTaskMapper.updateAllBusiflWaitTask(busiflWaitTask);
                busiflInstStepMapper.updateBusiflInstStep(busiflInstStep);
            } else {
                /** 审批意见为拒件,如果当前任务并发审批模式1-正常模式，关闭当前节点归属所有任务和步骤信息*/
                busiflWaitTaskMapper.updateAllBusiflWaitTask(busiflWaitTask);
                busiflInstStepMapper.updateBusiflInstStep(busiflInstStep);
                //关闭流程实例，迁移待办数据到历史任务
                closeInstance(instanceId, currentWaitTask, currentUser);
            }
        } else {
            busiflWaitTaskMapper.updateBusiflWaitTask(busiflWaitTask);
            busiflInstStepMapper.updateBusiflInstStepByUser(busiflInstStep);
            if (untreatedTask == 1 && FlowConstants.STEP_TYPE_END.equals(currentStep.getStepType())) {
                //如果是结束节点,并且剩余最后一个任务，则关闭流程实例，迁移待办数据到历史任务
                closeInstance(instanceId, currentWaitTask, currentUser);
            }
        }
    }

    /**
     * 关闭流程实例，待办数据转移到历史待办
     *
     * @param instanceId
     * @param currentWaitTask
     * @param currentUser
     * @return void
     * @throws
     * @Title: closeInstance
     * @author JHON
     * @Date 2021/12/1 14:03
     **/
    public void closeInstance(String instanceId, BusiflWaitTask currentWaitTask, SysUser currentUser) {
        BusiflInstance busiflInstance = new BusiflInstance();
        busiflInstance.setInstanceId(instanceId);
        busiflInstance.setInstState("3");
        busiflInstance.setStopTime(DateUtils.getNowDate());
        busiflInstance.setStopUser(currentUser.getUserId());
        busiflInstanceMapper.updateBusiflInstance(busiflInstance);
        //待办数据转移到历史待办
        currentWaitTask.setInstanceId(instanceId);
        busiflWaitTaskMapper.insertHistoryWaitTask(currentWaitTask);
        //删除待办任务数据
        busiflWaitTaskMapper.deleteBusiflWaitTaskByInstanceId(instanceId);
    }

    /**
     * 获取不同处理意见的并发任务步骤信息
     *
     * @param taskBatchId
     * @param stepId
     * @param approveType
     * @return java.util.List<com.xydtech.busiflw.domain.BusiflInstStep>
     * @throws
     * @Title: getParallelTaskList
     * @author JHON
     * @Date 2021/12/1 14:24
     **/
    public List<BusiflInstStep> getParallelTaskList(String taskBatchId, Long stepId, String approveType) {
        BusiflInstStep busiflInstStep = new BusiflInstStep();
        busiflInstStep.setTaskBatchId(taskBatchId);
        busiflInstStep.setStepId(stepId);
        busiflInstStep.setApproveType(approveType);
        return busiflInstStepMapper.selectBusiflInstStepList(busiflInstStep);
    }

    /**
     * 组装并发送UNIPUSH消息推送到消息队列中，等待消费者进行处理
     *
     * @param receiverUserId 接收人的用户ID
     * @param taskId         任务ID
     * @param versionId      流程版本ID
     * @param instanceId     流程实例ID
     * @param stepId         流程步骤
     * @param approveType    审批意见:T-同意；R-退回；F-拒绝（这里应该不会出现这个状态）
     * @param keyInfo        客户相关信息{"cname":"张三","cardNum":"511423199111150019","phoneNum":"18611111144"}
     * @param flowName       流程名称
     * @return void
     * @throws
     * @author Daniel
     * @date 2022/3/17 15:58
     */
    public void packageAndSendAppUniPushMessage(Long receiverUserId, Long taskId, Long versionId,
                                                String instanceId, Long stepId, String approveType, String keyInfo,
                                                String flowName) {
        String title = "待办任务提醒！";
        String content = "";
        //提取客户信息
        JSONObject keyInfoObj = JSONObject.parseObject(keyInfo);
        if (FlowConstants.APPROVE_TYPE_T.equals(approveType)) {
            //同意
            content = "业务编号【" + instanceId + "】名称【" + keyInfoObj.get("cname") + "】提交的【" + flowName + "】";
        } else if (FlowConstants.APPROVE_TYPE_R.equals(approveType)) {
            //退回
            content = "业务编号【" + instanceId + "】名称【" + keyInfoObj.get("cname") + "】退回的【" + flowName + "】";
        }

        Map<String, Object> pushParams = new HashMap<>();
        pushParams.put("taskId", taskId);
        pushParams.put("versionId", versionId);
        pushParams.put("instanceId", instanceId);
        pushParams.put("stepId", stepId);
        pushParams.put("pushType", UniPushConfig.PUSH_TYPE_WAITDO);
        //TODO 推送注释
        //uniPushService.sendAppMessageIntoActiveMQQueues(receiverUserId + "", title, content, pushParams);
    }

    /**
     * 并发任务提交
     *
     * @param currentStep
     * @param currentWaitTask
     * @param instanceId
     * @param currentUser
     * @param approveType
     * @param approveMemo
     * @param keyInfo
     * @param choiceApproveUserList
     * @return com.xydtech.common.core.domain.AjaxResult
     * @throws
     * @Title: parallelTaskSubmit
     * @author JHON
     * @Date 2022/10/26 10:58
     **/
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult parallelTaskSubmit(WflFlowstep currentStep, BusiflWaitTask currentWaitTask, String instanceId, SysUser currentUser, String approveType, String approveMemo, String keyInfo, String choiceApproveUserList, String salt) {
        //查询未处理任务数,最后一个人提交流程才流转到下一节点
        BusiflWaitTask untreatedWaitTask = new BusiflWaitTask();
        untreatedWaitTask.setInstanceId(instanceId);
        untreatedWaitTask.setStepId(currentStep.getStepId());
        untreatedWaitTask.setSts("1");
        untreatedWaitTask.setTaskBatchId(currentWaitTask.getTaskBatchId());
        List<BusiflWaitTask> untreatedWaitTaskTaskList = busiflWaitTaskMapper.selectBusiflWaitTaskList(untreatedWaitTask);
        //未处理任务数
        int untreatedTask = untreatedWaitTaskTaskList.size();
        if (untreatedTask == 1) {
            /**运行流程节点逻辑单元*/
            AjaxResult ajaxResult = businessFlowLogicService.flowLogicRunning(currentStep.getVersionId(), instanceId, currentStep.getStepId(), keyInfo, approveType, currentUser);
            if (!Constants.SUCCESS.equals(ajaxResult.get(Constants.CODE).toString())) {
                return AjaxResult.error(ajaxResult.get(Constants.MSG).toString());
            }
        }
        //当前步骤节点是并发策略的话需要判断并发审批模式（1-正常模式 2-投票模式）,2-投票模式判断已同意数量
        if (FlowConstants.APPROVE_MODE_2.equals(currentStep.getApprovMode())) {
            //查询已同意处理任务数
            int agreeTask = getParallelTaskList(currentWaitTask.getTaskBatchId(), currentWaitTask.getStepId(), "T").size();
            //查询已拒件处理任务数
            int refuseTask = getParallelTaskList(currentWaitTask.getTaskBatchId(), currentWaitTask.getStepId(), "F").size();
            //查询已退回处理任务数
            List<BusiflInstStep> returnTaskList = getParallelTaskList(currentWaitTask.getTaskBatchId(), currentWaitTask.getStepId(), "R");
            int returnTask = returnTaskList.size();
            //通过人数(任务并发使用)并发审批模式为投票模式启用
            Long passPop = currentStep.getPassPop();
            //未处理任务数只剩当前任务
            if (untreatedTask == 1) {
                if (approveType.startsWith(FlowConstants.APPROVE_TYPE_T)) {
                    agreeTask = agreeTask + 1;
                } else if (approveType.startsWith(FlowConstants.APPROVE_TYPE_F)) {
                    refuseTask = refuseTask + 1;
                } else if (approveType.startsWith(FlowConstants.APPROVE_TYPE_R)) {
                    returnTask = returnTask + 1;
                }
                /**查询下一个流程节点信息*/
                //WflFlowstep nextStep = new WflFlowstep();
                //nextStepName = nextStep.getStepName();
                //同意人数大于等于配置要求通过人数，则流转的下一环节
                if (agreeTask >= passPop) {
                    String nextStepName = "";
                    /**同意时，如果当前步骤节点不是结束节点生成待办任务*/
                    if (!FlowConstants.STEP_TYPE_END.equals(currentStep.getStepType())) {
                        /**查询下一个流程节点信息*/
                        WflFlowstep nextStep = getNextStepInfo(currentStep.getVersionId(), currentStep.getOrderNum(), instanceId, keyInfo);
                        nextStepName = nextStep.getStepName();
                        /**生成任务批次号*/
                        String taskBatchId = new StringBuilder().append(DateUtils.dateMillisecondNow()).append(String.format("%0" + 8 + "d", nextStep.getStepId() + currentUser.getUserId())).toString();
                        /**查询下一节点审批人*/
                        List<SysUser> userList = getApproveUserList(instanceId, nextStep, currentUser, choiceApproveUserList, salt);
                        if (userList.size() > 0) {
                            if (nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_3) || nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_4)) {
                                /**下一节点分派策略是3-任务并发或 4-任务多选并发，判断下一节点审批人数量是否满足参与人数限制条件*/
                                if (userList.size() < nextStep.getApprovPop()) {
                                    return AjaxResult.error("下一审批环节【" + nextStep.getStepName() + "】需要" + nextStep.getApprovPop() + "人审批，请给该岗位分配更多人员！");
                                }
                            }
                            /**生成下一节点待办任务*/
                            if (nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_1) || nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_2)) {
                                /**下一节点分派策略是1-任务抢先 2-任务多选抢先，初始化流程步骤信息时步骤处理人为空，只生成一条步骤信息*/
                                insertBusiflInstStep(instanceId, taskBatchId, nextStep, currentUser, null);
                                for (SysUser nextUser : userList) {
                                    /**创建下一节点待办任务*/
                                    createTask(currentStep.getVersionId(), instanceId, taskBatchId, nextStep, currentUser, nextUser, "2", FlowConstants.APPROVE_TYPE_T, keyInfo, nextStep.getStepName());
                                }
                            } else if (nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_3) || nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_4)) {
                                for (SysUser nextUser : userList) {
                                    /**创建下一节点待办任务*/
                                    createTask(currentStep.getVersionId(), instanceId, taskBatchId, nextStep, currentUser, nextUser, "2", FlowConstants.APPROVE_TYPE_T, keyInfo, nextStep.getStepName());
                                    /**下一节点分派策略是3-任务并发或 4-任务多选并发，初始化流程步骤信息时步骤处理人为接收人，每个人都生成步骤信息*/
                                    insertBusiflInstStep(instanceId, taskBatchId, nextStep, currentUser, nextUser);
                                }
                            }
                        } else {
                            return AjaxResult.error("下一审批环节【" + nextStep.getStepName() + "】未配置审批信息！");
                        }

                    }
                    //关闭并发任务
                    closeParallelTask(instanceId, currentWaitTask, currentStep, currentUser, approveType, approveMemo, untreatedTask);
                    if ("".equals(nextStepName)) {
                        return AjaxResult.success("同意提交成功！");
                    } else {
                        return AjaxResult.success("提交到" + nextStepName + "环节！");
                    }
                } else {
                    //同意人数小于要求通过人数，判断退回和拒件数，决定流程走向
                    if (refuseTask > returnTask) {
                        //关闭并发任务
                        closeParallelTask(instanceId, currentWaitTask, currentStep, currentUser, approveType, approveMemo, untreatedTask);
                        return AjaxResult.success("提交成功！");
                    } else {
                        /**查询退回到的业务流程步骤处理信息*/
                        BusiflInstStep returnInstStep = new BusiflInstStep();
                        returnInstStep.setStepId(Long.valueOf(returnTaskList.get(0).getApproveType().replace("R", "")));
                        returnInstStep.setInstanceId(instanceId);
                        returnInstStep.setSts("1");
                        List<BusiflInstStep> returnInstStepList = busiflInstStepMapper.selectcorrelationUserList(returnInstStep);
                        //查询退回节点信息
                        WflFlowstep returnNextStep = new WflFlowstep();
                        returnNextStep.setStepId(returnInstStep.getStepId());
                        returnNextStep.setVersionId(currentStep.getVersionId());
                        List<WflFlowstep> returnNextStepList = wflFlowstepMapper.selectWflFlowstepList(returnNextStep);
                        /**生成任务批次号*/
                        String taskBatchId = new StringBuilder().append(DateUtils.dateMillisecondNow()).append(String.format("%0" + 8 + "d", returnNextStep.getStepId() + currentUser.getUserId())).toString();
                        /**下一节点 是任务抢先，生成一条数据，任务并发生成多条数据*/
                        if (FlowConstants.TASK_POLICY_1.equals(returnNextStepList.get(0).getTaskPolicy()) || FlowConstants.TASK_POLICY_2.equals(returnNextStepList.get(0).getTaskPolicy())) {
                            //获取退回节点当时的处理人
                            SysUser nextUser = sysUserMapper.selectUserById(returnInstStepList.get(0).getStopUser());
                            if (nextUser != null) {
                                try {
                                    //数据解密（手机号、身份证号）
                                    if (!StringUtils.objIsNullOrEmpty(nextUser.getPhonenumber())) {
                                        nextUser.setPhonenumber(AESEncryptionUtils.decrypt(nextUser.getPhonenumber(), salt));
                                    }
                                    if (!StringUtils.objIsNullOrEmpty(nextUser.getCardNum())) {
                                        nextUser.setCardNum(AESEncryptionUtils.decrypt(nextUser.getCardNum(), salt));
                                    }
                                } catch (Exception e) {
                                    throw new RuntimeException(e);
                                }
                            }
                            if (nextUser == null) {
                                return AjaxResult.error("退回节点接收人不存在，可能该用户已被删除或停用！");
                            }
                            /**生成业务流程节点数据*/
                            insertBusiflInstStep(instanceId, taskBatchId, returnNextStepList.get(0), currentUser, nextUser);
                            /**创建下一节点待办任务*/
                            createTask(currentStep.getVersionId(), instanceId, taskBatchId, returnNextStepList.get(0), currentUser, nextUser, "3", FlowConstants.APPROVE_TYPE_R, keyInfo, returnNextStepList.get(0).getStepName());
                        } else {
                            for (int i = 0; i < returnInstStepList.size(); i++) {
                                //获取退回节点当时的处理人
                                SysUser nextUser = sysUserMapper.selectUserById(returnInstStepList.get(i).getStopUser());
                                if (nextUser != null) {
                                    try {
                                        //数据解密（手机号、身份证号）
                                        if (!StringUtils.objIsNullOrEmpty(nextUser.getPhonenumber())) {
                                            nextUser.setPhonenumber(AESEncryptionUtils.decrypt(nextUser.getPhonenumber(), salt));
                                        }
                                        if (!StringUtils.objIsNullOrEmpty(nextUser.getCardNum())) {
                                            nextUser.setCardNum(AESEncryptionUtils.decrypt(nextUser.getCardNum(), salt));
                                        }
                                    } catch (Exception e) {
                                        throw new RuntimeException(e);
                                    }
                                }
                                if (nextUser == null) {
                                    return AjaxResult.error("退回节点接收人不存在，可能该用户被删除或停用！");
                                }
                                /**创建退回节点待办任务*/
                                createTask(currentStep.getVersionId(), instanceId, taskBatchId, returnNextStepList.get(0), currentUser, nextUser, "3", FlowConstants.APPROVE_TYPE_R, keyInfo, returnNextStepList.get(0).getStepName());
                                /**退回节点节点分派策略是2-任务并发或 3-任务多选并发，步骤处理人为接收人，每个人都生成步骤信息*/
                                insertBusiflInstStep(instanceId, taskBatchId, returnNextStepList.get(0), currentUser, nextUser);
                            }
                        }
                        //关闭并发任务
                        closeParallelTask(instanceId, currentWaitTask, currentStep, currentUser, approveType, approveMemo, untreatedTask);
                        return AjaxResult.success("退回到" + returnNextStepList.get(0).getStepName() + "环节！");
                    }
                }
            } else {
                //关闭并发任务
                closeParallelTask(instanceId, currentWaitTask, currentStep, currentUser, approveType, approveMemo, untreatedTask);
                return AjaxResult.success("提交成功,当前并发任务等待其他人提交完成进入下一环节！");
            }

        } else {
            if (approveType.startsWith(FlowConstants.APPROVE_TYPE_T)) {
                String nextStepName = "";
                /**同意时，如果当前步骤节点不是结束节点并且只剩当前任务未提交*/
                if (!FlowConstants.STEP_TYPE_END.equals(currentStep.getStepType()) && untreatedTask == 1) {
                    /**查询下一个流程节点信息*/
                    WflFlowstep nextStep = getNextStepInfo(currentStep.getVersionId(), currentStep.getOrderNum(), instanceId, keyInfo);
                    nextStepName = nextStep.getStepName();
                    /**生成任务批次号*/
                    String taskBatchId = new StringBuilder().append(DateUtils.dateMillisecondNow()).append(String.format("%0" + 8 + "d", nextStep.getStepId() + currentUser.getUserId())).toString();
                    /**查询下一节点审批人*/
                    List<SysUser> userList = getApproveUserList(instanceId, nextStep, currentUser, choiceApproveUserList, salt);
                    if (userList.size() > 0) {
                        /**下一节点分派策略是3-任务并发或 4-任务多选并发，判断下一节点审批人数量是否满足参与人数限制条件*/
                        if (userList.size() < nextStep.getApprovPop()) {
                            return AjaxResult.error("下一审批环节【" + nextStep.getStepName() + "】需要" + nextStep.getApprovPop() + "人审批，请给该岗位分配更多人员！");
                        }

                        /**生成下一节点待办任务*/
                        if (nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_1) || nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_2)) {
                            /**下一节点分派策略是1-任务抢先 2-任务多选抢先，初始化流程步骤信息时步骤处理人为空，只生成一条步骤信息*/
                            insertBusiflInstStep(instanceId, taskBatchId, nextStep, currentUser, null);
                            for (SysUser nextUser : userList) {
                                /**创建下一节点待办任务*/
                                createTask(currentStep.getVersionId(), instanceId, taskBatchId, nextStep, currentUser, nextUser, "2", FlowConstants.APPROVE_TYPE_T, keyInfo, nextStep.getStepName());
                            }
                        } else if (nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_3) || nextStep.getTaskPolicy().equals(FlowConstants.TASK_POLICY_4)) {
                            for (SysUser nextUser : userList) {
                                /**创建下一节点待办任务*/
                                createTask(currentStep.getVersionId(), instanceId, taskBatchId, nextStep, currentUser, nextUser, "2", FlowConstants.APPROVE_TYPE_T, keyInfo, nextStep.getStepName());
                                /**下一节点分派策略是3-任务并发或 4-任务多选并发，初始化流程步骤信息时步骤处理人为接收人，每个人都生成步骤信息*/
                                insertBusiflInstStep(instanceId, taskBatchId, nextStep, currentUser, nextUser);
                            }
                        }
                    } else {
                        return AjaxResult.error("下一审批环节【" + nextStep.getStepName() + "】未配置审批信息！");
                    }
                    //关闭并发任务
                    closeParallelTask(instanceId, currentWaitTask, currentStep, currentUser, approveType, approveMemo, untreatedTask);
                    if ("".equals(nextStepName)) {
                        return AjaxResult.success("同意提交成功！");
                    } else {
                        return AjaxResult.success("提交到" + nextStepName + "环节！");
                    }
                } else {
                    //关闭并发任务
                    closeParallelTask(instanceId, currentWaitTask, currentStep, currentUser, approveType, approveMemo, untreatedTask);
                    return AjaxResult.success("提交成功,当前并发任务等待其他人提交完成进入下一环节！");
                }

            } else if (approveType.startsWith(FlowConstants.APPROVE_TYPE_F)) {
                //关闭并发任务
                closeParallelTask(instanceId, currentWaitTask, currentStep, currentUser, approveType, approveMemo, untreatedTask);
                return AjaxResult.success("拒件提交成功！");
            } else if (approveType.startsWith(FlowConstants.APPROVE_TYPE_R)) {
                /**查询退回到的业务流程步骤处理信息*/
                BusiflInstStep returnInstStep = new BusiflInstStep();
                returnInstStep.setStepId(Long.valueOf(approveType.replace("R", "")));
                returnInstStep.setInstanceId(instanceId);
                returnInstStep.setSts("1");
                List<BusiflInstStep> returnInstStepList = busiflInstStepMapper.selectcorrelationUserList(returnInstStep);
                //查询退回节点信息
                WflFlowstep returnNextStep = new WflFlowstep();
                returnNextStep.setStepId(returnInstStep.getStepId());
                returnNextStep.setVersionId(currentStep.getVersionId());
                List<WflFlowstep> returnNextStepList = wflFlowstepMapper.selectWflFlowstepList(returnNextStep);
                /**生成任务批次号*/
                String taskBatchId = new StringBuilder().append(DateUtils.dateMillisecondNow()).append(String.format("%0" + 8 + "d", returnNextStep.getStepId() + currentUser.getUserId())).toString();
                /**下一节点 是任务抢先，生成一条数据，任务并发生成多条数据*/
                if (FlowConstants.TASK_POLICY_1.equals(returnNextStepList.get(0).getTaskPolicy()) || FlowConstants.TASK_POLICY_2.equals(returnNextStepList.get(0).getTaskPolicy())) {
                    //获取退回节点当时的处理人
                    SysUser nextUser = sysUserMapper.selectUserById(returnInstStepList.get(0).getStopUser());
                    if (nextUser != null) {
                        try {
                            //数据解密（手机号、身份证号）
                            if (!StringUtils.objIsNullOrEmpty(nextUser.getPhonenumber())) {
                                nextUser.setPhonenumber(AESEncryptionUtils.decrypt(nextUser.getPhonenumber(), salt));
                            }
                            if (!StringUtils.objIsNullOrEmpty(nextUser.getCardNum())) {
                                nextUser.setCardNum(AESEncryptionUtils.decrypt(nextUser.getCardNum(), salt));
                            }
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }
                    if (nextUser == null) {
                        return AjaxResult.error("退回节点接收人不存在，可能该用户已被删除或停用！");
                    }
                    /**生成业务流程节点数据*/
                    insertBusiflInstStep(instanceId, taskBatchId, returnNextStepList.get(0), currentUser, nextUser);
                    /**创建下一节点待办任务*/
                    createTask(currentStep.getVersionId(), instanceId, taskBatchId, returnNextStepList.get(0), currentUser, nextUser, "3", FlowConstants.APPROVE_TYPE_R, keyInfo, returnNextStepList.get(0).getStepName());
                } else {
                    for (int i = 0; i < returnInstStepList.size(); i++) {
                        //获取退回节点当时的处理人
                        SysUser nextUser = sysUserMapper.selectUserById(returnInstStepList.get(i).getStopUser());
                        if (nextUser != null) {
                            try {
                                //数据解密（手机号、身份证号）
                                if (!StringUtils.objIsNullOrEmpty(nextUser.getPhonenumber())) {
                                    nextUser.setPhonenumber(AESEncryptionUtils.decrypt(nextUser.getPhonenumber(), salt));
                                }
                                if (!StringUtils.objIsNullOrEmpty(nextUser.getCardNum())) {
                                    nextUser.setCardNum(AESEncryptionUtils.decrypt(nextUser.getCardNum(), salt));
                                }
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        }
                        if (nextUser == null) {
                            return AjaxResult.error("退回节点接收人不存在，可能该用户被删除或停用！");
                        }
                        /**创建退回节点待办任务*/
                        createTask(currentStep.getVersionId(), instanceId, taskBatchId, returnNextStepList.get(0), currentUser, nextUser, "3", FlowConstants.APPROVE_TYPE_R, keyInfo, returnNextStepList.get(0).getStepName());
                        /**退回节点节点分派策略是2-任务并发或 3-任务多选并发，步骤处理人为接收人，每个人都生成步骤信息*/
                        insertBusiflInstStep(instanceId, taskBatchId, returnNextStepList.get(0), currentUser, nextUser);
                    }
                }
                //关闭并发任务
                closeParallelTask(instanceId, currentWaitTask, currentStep, currentUser, approveType, approveMemo, untreatedTask);
                return AjaxResult.success("退回到" + returnNextStepList.get(0).getStepName() + "环节！");
            } else {
                return AjaxResult.error("未获取到审批意见信息，请检查流程配置，确保对应岗位分配人员！");
            }
        }
    }
}
